home *** CD-ROM | disk | FTP | other *** search
/ MacHack 2001 / MacHack 2001.toast / pc / The Hacks / The Weakest Link / source / Promiscuity.cp next >
Encoding:
Text File  |  2001-06-23  |  7.3 KB  |  286 lines

  1. #include "EnetVersion.h"
  2. #include <stropts.h>
  3. #include <dlpi.h>
  4. #include <poll.h>
  5. #include <DriverServices.h>
  6. #include <OpenTransport.h>
  7. #include <stdio.h>
  8.  
  9. #define MACOS 1
  10. #include "EnetUser.h"
  11.  
  12. #include "Promiscuity.h"
  13. #include "SortFrames.h"
  14.  
  15. //#define printf(...)
  16.  
  17. #define UseEndPoint 1
  18.  
  19. /******************************************************************************/
  20.  
  21. // dl_enabpromisc_req() does a DL_PROMISCON_REQ.
  22. // The stream will receive all packets.
  23. // Returns false if there was an error.
  24. static int dl_enabpromisc_req(int stream)
  25. {
  26.     struct strbuf                control;
  27.     unsigned char                enabpromiscBuffer[sizeof(dl_promiscon_req_t)];
  28.     dl_promiscon_req_t *        enabpromiscReq =
  29.                                     (dl_promiscon_req_t *)enabpromiscBuffer;
  30.     unsigned char                okAckBuffer[sizeof(dl_ok_ack_t)];
  31.     dl_ok_ack_t *                okAck = (dl_ok_ack_t *)okAckBuffer;
  32.     int                            flags;
  33.     int                            err = noErr;
  34.     extern int errno;
  35.     
  36.     // Prepare a DL_PROMISCON_REQ message.
  37.     enabpromiscReq->dl_primitive = DL_PROMISCON_REQ;
  38.     enabpromiscReq->dl_level = DL_PROMISC_PHYS;
  39.  
  40.     // Send the DL_PROMISCON_REQ message downstream to the DLPI module.
  41.     control.len = sizeof(enabpromiscBuffer);
  42.     control.buf = (char *)enabpromiscBuffer;
  43.     if ( (err = putmsg(stream, &control, NULL, 0)) < 0) 
  44.     {
  45.         //printf("dl_enabpromisc_req: putmsg errno %d\n", errno);
  46.         goto error;
  47.     }
  48.  
  49.     // Get the DL_OK_ACK message sent upstream by the DLPI module.
  50.     control.maxlen = sizeof(okAckBuffer);
  51.     control.len = 0;
  52.     control.buf = (char *)okAckBuffer;
  53.     flags = RS_HIPRI;
  54.     if ((err = getmsg(stream, &control, NULL, &flags)) < 0) {
  55.         printf("dl_enabpromisc_req: getmsg errno %d\n", err);
  56.         goto error;
  57.     }
  58.     if (control.len < sizeof(UInt32)) {
  59.         printf("dl_enabpromisc_req: control.len %d < %d\n", control.len, sizeof(UInt32));
  60.         err = -1;
  61.         goto error;
  62.     }
  63.     if (okAck->dl_primitive == DL_ERROR_ACK) {
  64.         printf("dl_enabpromisc_req: DL_ERROR_ACK\n");
  65.         err = -2;
  66.         goto error;
  67.     }
  68.     if (okAck->dl_primitive != DL_OK_ACK) {
  69.         printf("dl_enabpromisc_req: 0x%08X not DL_OK_ACK\n",
  70.                okAck->dl_primitive);
  71.         err = -3;
  72.         goto error;
  73.     }
  74.  
  75.     // All done, no error, return true.
  76.     return 0;
  77.  
  78.     // Return false if there was an error.
  79. error:
  80.     if ( err == -1 )
  81.         return( errno );
  82.     else
  83.         return err;
  84.  
  85. }
  86.  
  87. /******************************************************************************/
  88.  
  89. // dl_disabpromisc_req() does a DL_PROMISCOFF_REQ.
  90. // The stream will receive all packets.
  91. // Returns false if there was an error.
  92. static Boolean dl_disabpromisc_req(int stream)
  93. {
  94.     struct strbuf                control;
  95.     unsigned char                enabpromiscBuffer[sizeof(dl_promiscon_req_t)];
  96.     dl_promiscon_req_t *        enabpromiscReq =
  97.                                     (dl_promiscon_req_t *)enabpromiscBuffer;
  98.     unsigned char                okAckBuffer[sizeof(dl_ok_ack_t)];
  99.     dl_ok_ack_t *                okAck = (dl_ok_ack_t *)okAckBuffer;
  100.     int                            flags;
  101.     int                            err;
  102.  
  103.     // Prepare a DL_PROMISCOFF_REQ message.
  104.     enabpromiscReq->dl_primitive = DL_PROMISCOFF_REQ;
  105.     enabpromiscReq->dl_level = DL_PROMISC_PHYS;
  106.  
  107.     // Send the DL_PROMISCON_REQ message downstream to the DLPI module.
  108.     control.len = sizeof(enabpromiscBuffer);
  109.     control.buf = (char *)enabpromiscBuffer;
  110.     if ((err = putmsg(stream, &control, NULL, 0)) < 0) {
  111.         //printf("dl_disabpromisc_req: putmsg errno %d\n", errno);
  112.         goto error;
  113.     }
  114.  
  115.     // Get the DL_OK_ACK message sent upstream by the DLPI module.
  116.     control.maxlen = sizeof(okAckBuffer);
  117.     control.len = 0;
  118.     control.buf = (char *)okAckBuffer;
  119.     flags = RS_HIPRI;
  120.     if ((err = getmsg(stream, &control, NULL, &flags)) < 0) {
  121.         printf("dl_disabpromisc_req: getmsg errno %d\n", err);
  122.         goto error;
  123.     }
  124.     if (control.len < sizeof(UInt32)) {
  125.         printf("dl_disabpromisc_req: control.len %d < %d\n",
  126.                control.len,
  127.                sizeof(UInt32));
  128.         goto error;
  129.     }
  130.     if (okAck->dl_primitive == DL_ERROR_ACK) {
  131.         printf("dl_disabpromisc_req: DL_ERROR_ACK\n");
  132.         goto error;
  133.     }
  134.     if (okAck->dl_primitive != DL_OK_ACK) {
  135.         printf("dl_enabpromisc_req: 0x%08X not DL_OK_ACK\n",
  136.                okAck->dl_primitive);
  137.         goto error;
  138.     }
  139.  
  140.     // All done, no error, return true.
  141.     return true;
  142.  
  143.     // Return false if there was an error.
  144. error:
  145.     return false;
  146.  
  147. }
  148.  
  149. /******************************************************************************/
  150.  
  151. // dl_unitdata_ind() handles a DL_UNITDATA_IND.
  152. // This is the basic receive operation.
  153. // This function blocks until a packet has been received.
  154. // Returns false if there was an error.
  155. static Boolean
  156.     dl_unitdata_ind(int stream,
  157.                     UInt32 maxPacketSize,
  158.                     char *packet,
  159.                     UInt32 *packetSize,
  160.                     EnetAddressPtr address,
  161.                     Boolean block)
  162. {
  163.     struct pollfd                pfd[1];
  164.     int                            n;
  165.     struct strbuf                control;
  166.     struct strbuf                data;
  167.     int                            flags;
  168.     unsigned char        unitdataIndBuffer[sizeof(dl_unitdata_ind_t) + 26];
  169.     dl_unitdata_ind_t *    unitdataInd = (dl_unitdata_ind_t *)unitdataIndBuffer;
  170.     static int                    taskCount;
  171.  
  172.     for (;;) {
  173.         // Poll for an input message ready.
  174.         pfd[0].fd = stream;
  175.         pfd[0].events = POLLIN;
  176.         if (((n = poll(pfd, 1, block ? 1 : 0)) < 0) || (n > 1)) {
  177.             printf("WDiskServer: poll error, n = %d\n", n);
  178.             break;
  179.         }
  180.         // If timeout, do SystemTask() and check for Quit.
  181.         if (n == 0) {
  182.             if (block || ((taskCount++ & 1023) == 0)) {
  183.                 //SystemTask();
  184.             }
  185.             if (!block)
  186.                 goto error;
  187.             continue;
  188.         }
  189.         // A message is ready.  Apply getmsg().
  190.         control.maxlen = sizeof(unitdataIndBuffer);
  191.         control.len = 0;
  192.         control.buf = (char *)unitdataIndBuffer;
  193.         data.maxlen = maxPacketSize;
  194.         data.len = 0;
  195.         data.buf = packet;
  196.         flags = 0;
  197.         if ((n = getmsg(stream, &control, &data, &flags)) != 0) {
  198.             printf("WDiskServer: getmsg error, n = %d\n", n);
  199.             continue;
  200.         }
  201.         // If control length is -1, then it is a FAST-PATH message.
  202.         // Note that a FAST-PATH message does not have the source address.
  203.         if (control.len == -1)
  204.             ;
  205.         // Error if the control length is out of bounds.
  206.         else if (control.len < sizeof(UInt32)) {
  207.             printf("WDiskServer: control.len %d < %d\n",
  208.                    control.len,
  209.                    sizeof(UInt32));
  210.             continue;
  211.         }
  212.         // Error if the message is not DL_UNITDATA_IND.
  213.         else if (unitdataInd->dl_primitive != DL_UNITDATA_IND) {
  214.         //    printf("WDiskServer: dl_primitive %d != %d\n",
  215.         //           unitdataInd->dl_primitive,
  216.         //           DL_UNITDATA_IND);
  217.             continue;
  218.         }
  219.         // Process the DL_UNITDATA_IND message.
  220.         // Note that a DL_UNITDATA_IND message has the source address.
  221.         else {
  222.             BlockMove(&unitdataIndBuffer[unitdataInd->dl_src_addr_offset],
  223.                       address,
  224.                       6);
  225.         }
  226.         // Export the packet size.
  227.         *packetSize = data.len;
  228.         break;
  229.     }
  230.  
  231.     // All done, no error, return true.
  232.     return true;
  233.  
  234.     // Return false if there was an error.
  235. error:
  236.     return false;
  237.  
  238. }
  239.  
  240. /******************************************************************************/
  241.  
  242. //===
  243.  
  244. static int stream = -1;
  245.  
  246. int initPromiscuity(char *inDeviceName)
  247. {
  248. //    stream = stream_open("enet1", 0);
  249.     stream = stream_open(inDeviceName, 0);
  250.     if ( stream == nil )
  251.         return( noHardwareErr );
  252.     return dl_enabpromisc_req(stream);
  253. }
  254.  
  255. void idlePromiscuity(void)
  256. {
  257.     char                        rxP[1500];
  258.     Packet                        *p = (Packet*) rxP;
  259.     UInt32                        size;
  260.     UInt8                        address[6] = {0,};
  261.  
  262.     if (dl_unitdata_ind(stream, 1500, rxP, &size, address, true))
  263.     {
  264.         ConsumePacket( p, size );
  265.  
  266.         #if 0
  267.         if ((p->protocol == 6) && ((p->versionAndIHL & 0x0F) == 5))
  268.         {
  269.             if ((p->totalLength > 40) || (p->moreFlagsAndJunk & kFINBit))
  270.             {
  271.                 ConsumePacket( p );
  272.             }
  273.             else showBlob( 0 ); // yellow
  274.         }
  275.         else showBlob( 0 ); // yellow
  276.         #endif
  277.     }
  278. }
  279.  
  280. void termPromiscuity(void)
  281. {
  282.     dl_disabpromisc_req(stream);
  283. }
  284.  
  285.  
  286.